#!/usr/bin/env python3
"""
下载Swagger UI和ReDoc的静态资源到本地
从国内CDN源下载以提高速度
"""

import os
import requests
import zipfile
import shutil
from pathlib import Path
import json

def create_directories():
    """创建必要的目录结构"""
    directories = [
        "simpleapi/static/swagger-ui",
        "simpleapi/static/redoc"
    ]
    
    for directory in directories:
        Path(directory).mkdir(parents=True, exist_ok=True)
        print(f"✓ 创建目录: {directory}")

def download_file(url, filepath, description=""):
    """下载文件到指定路径"""
    try:
        print(f"正在下载 {description}: {url}")
        response = requests.get(url, stream=True, timeout=30)
        response.raise_for_status()
        
        with open(filepath, 'wb') as f:
            for chunk in response.iter_content(chunk_size=8192):
                f.write(chunk)
        
        print(f"✓ 下载完成: {filepath}")
        return True
    except Exception as e:
        print(f"✗ 下载失败 {filepath}: {e}")
        return False

def download_swagger_ui():
    """从国内CDN下载Swagger UI静态资源"""
    print("\n=== 下载 Swagger UI 资源 ===")
    
    # 使用BootCDN (国内CDN)
    base_url = "https://cdn.bootcdn.net/ajax/libs/swagger-ui"
    version = "5.17.14"
    
    swagger_files = [
        {
            "url": f"{base_url}/{version}/swagger-ui-bundle.js",
            "path": "simpleapi/static/swagger-ui/swagger-ui-bundle.js",
            "desc": "Swagger UI Bundle JS"
        },
        {
            "url": f"{base_url}/{version}/swagger-ui-standalone-preset.js", 
            "path": "simpleapi/static/swagger-ui/swagger-ui-standalone-preset.js",
            "desc": "Swagger UI Standalone Preset JS"
        },
        {
            "url": f"{base_url}/{version}/swagger-ui.css",
            "path": "simpleapi/static/swagger-ui/swagger-ui.css", 
            "desc": "Swagger UI CSS"
        }
    ]
    
    success_count = 0
    for file_info in swagger_files:
        if download_file(file_info["url"], file_info["path"], file_info["desc"]):
            success_count += 1
    
    # 创建Swagger UI的HTML模板
    swagger_html = '''<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>SimpleAPI - Swagger UI</title>
    <link rel="stylesheet" type="text/css" href="./swagger-ui.css" />
    <style>
        html {
            box-sizing: border-box;
            overflow: -moz-scrollbars-vertical;
            overflow-y: scroll;
        }
        *, *:before, *:after {
            box-sizing: inherit;
        }
        body {
            margin:0;
            background: #fafafa;
        }
    </style>
</head>
<body>
    <div id="swagger-ui"></div>
    <script src="./swagger-ui-bundle.js"></script>
    <script src="./swagger-ui-standalone-preset.js"></script>
    <script>
                 window.onload = function() {
             const ui = SwaggerUIBundle({
                 url: '/api/openapi.json',
                dom_id: '#swagger-ui',
                deepLinking: true,
                presets: [
                    SwaggerUIBundle.presets.apis,
                    SwaggerUIStandalonePreset
                ],
                plugins: [
                    SwaggerUIBundle.plugins.DownloadUrl
                ],
                layout: "StandaloneLayout"
            });
        };
    </script>
</body>
</html>'''
    
    with open("simpleapi/static/swagger-ui/index.html", "w", encoding="utf-8") as f:
        f.write(swagger_html)
    print("✓ 创建 Swagger UI HTML 模板")
    
    return success_count == len(swagger_files)

def download_redoc():
    """从国内CDN下载ReDoc静态资源"""
    print("\n=== 下载 ReDoc 资源 ===")
    
    # 尝试多个CDN源
    redoc_sources = [
        {
            "name": "unpkg CDN",
            "url": "https://unpkg.com/redoc@2.1.5/bundles/redoc.standalone.js"
        },
        {
            "name": "jsDelivr CDN", 
            "url": "https://cdn.jsdelivr.net/npm/redoc@2.1.5/bundles/redoc.standalone.js"
        },
        {
            "name": "GitHub CDN",
            "url": "https://cdn.jsdelivr.net/gh/Redocly/redoc@v2.1.5/bundles/redoc.standalone.js"
        }
    ]
    
    redoc_files = []
    for source in redoc_sources:
        redoc_files.append({
            "url": source["url"],
            "path": "simpleapi/static/redoc/redoc.standalone.js",
            "desc": f"ReDoc Standalone JS ({source['name']})"
        })
    
    success_count = 0
    for file_info in redoc_files:
        if download_file(file_info["url"], file_info["path"], file_info["desc"]):
            success_count += 1
            break  # 只要有一个成功就停止
    
    # 创建ReDoc的HTML模板
    redoc_html = '''<!DOCTYPE html>
<html>
<head>
    <title>SimpleAPI - ReDoc</title>
    <meta charset="utf-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <style>
        body {
            margin: 0;
            padding: 0;
        }
    </style>
</head>
 <body>
     <redoc spec-url='/api/openapi.json'></redoc>
    <script src="./redoc.standalone.js"></script>
</body>
</html>'''
    
    with open("simpleapi/static/redoc/index.html", "w", encoding="utf-8") as f:
        f.write(redoc_html)
    print("✓ 创建 ReDoc HTML 模板")
    
    return success_count > 0

def download_alternative_sources():
    """从备用源下载资源（如果主要CDN失败）"""
    print("\n=== 尝试备用下载源 ===")
    
    # 备用CDN源
    alternative_sources = [
        {
            "name": "jsDelivr CDN",
            "swagger_base": "https://cdn.jsdelivr.net/npm/swagger-ui-dist@5.17.14",
            "redoc_base": "https://cdn.jsdelivr.net/npm/redoc@2.1.5/bundles"
        },
        {
            "name": "unpkg CDN", 
            "swagger_base": "https://unpkg.com/swagger-ui-dist@5.17.14",
            "redoc_base": "https://unpkg.com/redoc@2.1.5/bundles"
        }
    ]
    
    for source in alternative_sources:
        print(f"\n尝试从 {source['name']} 下载...")
        
        # Swagger UI 文件
        swagger_files = [
            ("swagger-ui-bundle.js", "simpleapi/static/swagger-ui/swagger-ui-bundle.js"),
            ("swagger-ui-standalone-preset.js", "simpleapi/static/swagger-ui/swagger-ui-standalone-preset.js"),
            ("swagger-ui.css", "simpleapi/static/swagger-ui/swagger-ui.css")
        ]
        
        swagger_success = True
        for filename, filepath in swagger_files:
            if not os.path.exists(filepath) or os.path.getsize(filepath) < 1000:
                url = f"{source['swagger_base']}/{filename}"
                if not download_file(url, filepath, f"Swagger UI {filename}"):
                    swagger_success = False
        
        # ReDoc 文件
        redoc_filepath = "simpleapi/static/redoc/redoc.standalone.js"
        if not os.path.exists(redoc_filepath) or os.path.getsize(redoc_filepath) < 1000:
            redoc_url = f"{source['redoc_base']}/redoc.standalone.js"
            download_file(redoc_url, redoc_filepath, "ReDoc standalone")
        
        if swagger_success:
            print(f"✓ 从 {source['name']} 下载成功")
            break

def verify_downloads():
    """验证下载的文件"""
    print("\n=== 验证下载文件 ===")
    
    required_files = [
        "simpleapi/static/swagger-ui/swagger-ui-bundle.js",
        "simpleapi/static/swagger-ui/swagger-ui-standalone-preset.js", 
        "simpleapi/static/swagger-ui/swagger-ui.css",
        "simpleapi/static/swagger-ui/index.html",
        "simpleapi/static/redoc/redoc.standalone.js",
        "simpleapi/static/redoc/index.html"
    ]
    
    all_good = True
    for filepath in required_files:
        if os.path.exists(filepath):
            size = os.path.getsize(filepath)
            if size > 0:
                print(f"✓ {filepath} ({size:,} bytes)")
            else:
                print(f"✗ {filepath} (文件为空)")
                all_good = False
        else:
            print(f"✗ {filepath} (文件不存在)")
            all_good = False
    
    return all_good

def main():
    """主函数"""
    print("SimpleAPI 静态资源下载器")
    print("=" * 50)
    
    # 创建目录
    create_directories()
    
    # 下载资源
    swagger_success = download_swagger_ui()
    redoc_success = download_redoc()
    
    # 如果主要CDN失败，尝试备用源
    if not swagger_success or not redoc_success:
        download_alternative_sources()
    
    # 验证下载
    if verify_downloads():
        print("\n🎉 所有静态资源下载完成！")
        print("\n接下来的步骤:")
        print("1. 运行 'python setup.py develop' 安装开发版本")
        print("2. 在你的应用中启用文档功能")
        print("3. 访问 /docs 查看 Swagger UI")
        print("4. 访问 /redoc 查看 ReDoc")
    else:
        print("\n❌ 部分文件下载失败，请检查网络连接后重试")
        return 1
    
    return 0

if __name__ == "__main__":
    exit(main()) 